#include "stdafx.h"
#include "Prefs.h"

#include "getopt.h"
#include "Utils.h"

#ifdef WIN32
#include <shlobj.h> /* SHGetFolderPath() */
#endif

/* ******************************************* */
Prefs * gPrefs=NULL;
#define CONST_DEFAULT_DATA_DIR      "data"

#define DEFAULT_PID_PATH        "/var/tmp/"
#define CONST_DEFAULT_WRITABLE_DIR  "/var/tmp"
#define CONST_DEFAULT_INSTALL_DIR   "/usr/local/share/mines"

/* SVN Release */
#define COMHUB_SVN_RELEASE "r328"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""

/* Architecture of this host */
#define PACKAGE_MACHINE "x86_64"
/* SVN release of this package */
#define PACKAGE_RELEASE "r328"
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.3"

Prefs::Prefs( char * app) {
	char * cp;
	if ((cp = strrchr(app, CONST_PATH_SEP)) != NULL)
		strcpy(mProgram ,cp + 1 );
	else strcpy(mProgram ,app);
	if ((cp = strrchr(mProgram, '.')) != NULL)	cp[0]=0;
	memset(mServer,0,sizeof(mServer));
	strcpy(mServer,"127.0.0.1");
	memset(mP1,0,sizeof(mP1));
	mPort = 9200;
	strcpy(mIndex,"perfdata");
	strcpy(mDomain,"localhost");
	mode = 0;
    mLogFd = NULL;
	mNoES = 0;

}

/* ******************************************* */

Prefs::~Prefs() {
  //printf("free 1 ");
  if(mLogFd) fclose(mLogFd);
  //printf("5 ");
  
}

/* ******************************************* */
void Prefs::Usage_s() {
  printf("%s %s v.%s (%s) - (C) 2014-06 atdm.liao\n\n"
	 "Usage:\n"
	 "  %s [-v] [-h] [-k] [-t] [-f <defaults file>] [-l <logFile name>] [-s <server name>]\n" 
	 "      [-p port] [-n <domain name>] [-i <index>]  [-c idc]  dataFile\n"
	 ,mProgram, PACKAGE_MACHINE, PACKAGE_VERSION, COMHUB_SVN_RELEASE,mProgram
	 );
}
/* C-binding needed by Win32 service call */
void Prefs::Usage() {

  printf("%s %s v.%s (%s) - (C) 2014-06 atdm.liao\n\n"
	 "Usage:\n"
	 "  %s [-v] [-h] [-k] [-t] [-f <defaults file>] [-l <logFile name>] [-s <server name>]\n"
	 "      [-p port] [-n <domain name>] [-i <index>] [-c idc]  dataFile name\n"
	 "\n"
	 "Options:\n"
	 "[--conf|-f]     <file name>    | Use the specified defaults file\n"
	 "[--log|-l]      <file name>    | Save log to file\n"
	 "[--server|-s]   <ES host>      | ES address, default 127.0.0.1 \n"
	 "[--port|-p]     number         | ES HTTP Port, default 9200\n"
     "[--name|-n]     domain         | Domain Name of Server, default localhost\n"
	 "[--index|-i]    <index>        | metadata, index of /{index}/{type}/{id} in ES\n"
	 "[--idc|-c]      <string>       | idc \n"
	 "[--test|-t]                    | Only parser input file\n"
	 "[--verbose|-v]    number       | Verbose tracing[0--6]\n"
	 "[--help|-h]                    | Help\n"
	 ,mProgram, PACKAGE_MACHINE, PACKAGE_VERSION, COMHUB_SVN_RELEASE,mProgram
	 );

  printf("\n");

  exit(0);
}

/* ******************************************* */

static const struct option long_options[] = {
  { "server",                         required_argument, NULL, 's' },
  { "port",                         required_argument, NULL, 'p' },
  { "log",                          required_argument, NULL, 'l' },
  { "name",                          required_argument, NULL, 'n' },
  { "index",                          required_argument, NULL, 'i' },
  { "conf",				            required_argument, NULL, 'f' },
  { "idc",				            required_argument, NULL, 'c' },
  { "test",                           no_argument,       NULL, 't' },
  { "verbose",                           required_argument,       NULL, 'v' },
  { "help",                              no_argument,       NULL, 'h' },
  /* End of options */
  { NULL,                                no_argument,       NULL,  0 }
};

/* ******************************************* */

int Prefs::SetOption(int optkey, char *optarg) {

	int k=0;
	//i B r p b   
  switch(optkey) {
  case 'f':
	  if( strlen(optarg)>1 ) return LoadFromFile(optarg);
	  return -1;
	  break;
  case 'v':
	  k= atoi(optarg);
	  if( k<0 )k=0;
	  if( k>MAX_TRACE_LEVEL ) k= MAX_TRACE_LEVEL;
    Trace::set_trace_level(k);
    break;
  case 'h':
    Usage();
    break;
  case 't':
	  mNoES =1;
	  break;
  case 's':
	  if( optarg ) strncpy(mServer,optarg,sizeof(mServer));
	  break;
  case 'n':
	  if( optarg ) strncpy(mDomain,optarg,sizeof(mDomain));
	  break;
  case 'p':
	  mPort = atoi(optarg);
	  if( mPort <= 0 ) mPort = 9200;
	  break;
  case 'i':
	  if( optarg ) strncpy(mIndex,optarg,sizeof(mIndex));
	  break;
  case 'l':
    if( mLogFd ) fclose(mLogFd);
    mLogFd = fopen(optarg, "a");
	if(mLogFd)
		printf("%s: set log file to %s\n",mProgram,optarg);
	else
		printf("%s: can not open log file %s\n",mProgram,optarg);
    break;
  case 'c':
	  if( optarg ) strncpy(mP1,optarg,sizeof(mP1));
	  break;
  default:
    return(-1);
  }

  return(0);
}



/* ******************************************* */
/* ******************************************* */

int Prefs::LoadFromCLI(int argc, char *argv[]) {
  int c;
  char buff[128];
#ifdef WIN32
  sprintf(buff,"%s.conf",mProgram);
#else
  sprintf(buff,"/etc/%s.conf",mProgram);
#endif

  FILE * fd = fopen(buff, "r");
  if( fd ){
	  fclose(fd);
	  LoadFromFile(buff);
  }
  while((c = getopt_long(argc, argv, "s:p:i:l:f:n:c:kv:th",
			 long_options, NULL)) != EOF ) {
	if( c== '?' ) {  Usage_s(); return -1; }
    if( SetOption(c, (char *)optarg)<0 ) return -1;
  }
  if( (argc-optind) <1 ) {
		  printf("%s: option require input file\n",mProgram);
		  Usage_s(); 
		  return -1; 
   }
   strcpy(mInput,argv[optind]);
   if( mServer[0] ==0 ) {
		  printf("%s: option require server\n",mProgram);
		  Usage_s(); 
		  return -1; 

   }
  return 0;
}

/* ******************************************* */

int Prefs::LoadFromFile(const char *path) {
  char buffer[512], *line, *key, *value;
  FILE *fd;
  const struct option *opt;

  fd = fopen(path, "r");

  if(fd == NULL) {
    Trace::traceEvent(TRACE_WARNING,"Config file %s not found", path);
    return(-1);
  }

  while(fd) {
    if(!(line = fgets(buffer, sizeof(buffer), fd)))
      break;

    line = Utils::Trim(line);

    if(strlen(line) < 1 || line[0] == '#')
      continue;

    key = line;
    key = Utils::Trim(key);
    
    value = strrchr(line, '=');

    /* Fallback to space */
    if(value == NULL) value = strrchr(line, ' ');
      
    if(value == NULL)
      value = &line[strlen(line)]; /* empty */
    else
      value[0] = 0, value = &value[1];
    value = Utils::Trim(value);

    //if(strlen(key) > 2) key = &key[2];
    //else key = &key[1];

    opt = long_options;
    while (opt->name != NULL) {
      if((strcmp(opt->name, key) == 0)
	  || ((key[1] == '\0') && (opt->val == key[0]))) {
        if( SetOption(opt->val, value)<0 ) return -1;
        break;
      }
      opt++;
    }
  }

  fclose(fd);
  return 1;
  //return(checkOptions());
}

